home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #2 / Amiga Plus CD - 2004 - No. 02.iso / AmiSoft / Misc / emu / Wzonka-Lad.lha / Wzonka-Lad / src / z80_misc.s < prev    next >
Text File  |  1999-06-19  |  23KB  |  1,164 lines

  1.  
  2. output_d0_to_a1:MACRO
  3.  
  4.         and.w    #$ff,d0
  5.         move.w    d0,d1
  6.         lsr.b    #4,d0
  7.         cmp.w    #$A,d0
  8.         blt.s    too_a\@
  9.         add.b    #'A'-$a,d0
  10.         bra.s    joo_a\@
  11. too_a\@:    add.b    #'0',d0
  12. joo_a\@:    move.b    d0,(a1)+
  13.  
  14.         and.b    #%1111,d1
  15.         cmp.w    #$A,d1
  16.         blt.s    too_b\@
  17.         add.b    #'A'-$a,d1
  18.         bra.s    joo_b\@
  19. too_b\@:    add.b    #'0',d1
  20. joo_b\@:    move.b    d1,(a1)+
  21.  
  22.         ENDM
  23.  
  24. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  25. ;        output debug data
  26. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  27.  
  28.         IFGT    GAMEBOY_DEBUG
  29.  
  30. debug_output:    ;btst.b    #6,$bfe001
  31.         ;bne.s    debug_output_no_output
  32.  
  33.         bra.s    debug_output_ok
  34.  
  35.         movem.l    d0-d7/a0-a6,-(SP)
  36.  
  37.         move.l    gb_memory,a6
  38.         add.l    #$fe00,a6
  39.         lea    debug_message,a1
  40.         move.w    #$A0-1,d7
  41.  
  42. debug_output_oam:
  43.         move.b    (a6)+,d0
  44.         output_d0_to_a1
  45.         dbra    d7,debug_output_oam
  46.  
  47.         move.b    #$A,(a1)+
  48.         move.b    #0,(a1)+
  49.         move.l    #$a2,d3
  50.  
  51.         bra.w    debug_output_output_size
  52.  
  53. debug_output_no_output:
  54.         move.b    (a0)+,d7
  55.         lsl.w    #8,d7                    ;d7 = d7*256.
  56.         jmp    (a1,d7.l)                ;jump and emulate.
  57.  
  58. debug_output_ok:movem.l    d0-d7/a0-a6,-(SP)
  59.  
  60.         move.w    d0,gbz80_de
  61.         move.w    d1,gbz80_bc
  62.         move.w    d2,gbz80_hl
  63.         move.w    d3,gbz80_fa
  64.  
  65.         lea    debug_flags,a1
  66.  
  67.         move.l    #"----",(a1)
  68.         move.b    #"-",4(a1)
  69.         btst    #0,d4
  70.         beq.s    debug_output_c
  71.         move.b    #"C",3(a1)
  72. debug_output_c:    btst    #2,d4
  73.         beq.s    debug_output_z
  74.         move.b    #"Z",(a1)
  75. debug_output_z:    btst    #8,d3
  76.         beq.s    debug_output_n
  77.         move.b    #"N",1(a1)
  78. debug_output_n:    tst.b    h_the_flag
  79.         beq.s    debug_output_h
  80.         move.b    #"H",2(a1)
  81. debug_output_h:    tst.b    i_flag
  82.         bne.s    debug_output_i
  83.         move.b    #"I",4(a1)
  84. debug_output_i:    
  85.  
  86.         lea    debug_oc,a1
  87.         move.b    (a0),d7
  88.         move.b    d7,d0
  89.         output_d0_to_a1
  90.  
  91.         lea    debug_cycles,a1
  92.         move.l    a5,d0
  93.         lsr.w    #8,d0
  94.         output_d0_to_a1
  95.         move.l    a5,d0
  96.         output_d0_to_a1
  97.  
  98.         lea    debug_list,a1
  99.         cmp.b    #$cb,d7
  100.         bne.s    debug_output_no_cb
  101.  
  102.         lea    debug_list_cb,a1
  103.         addq.l    #1,a0
  104.  
  105. debug_output_no_cb:
  106.         moveq.l    #0,d7
  107.         move.b    (a0),d7
  108.         lsl.l    #4,d7
  109.         add.l    d7,a1
  110.         lea    debug_command,a2
  111.         move.l    (a1)+,(a2)+
  112.         move.l    (a1)+,(a2)+
  113.         move.l    (a1)+,(a2)+
  114.         move.l    (a1)+,(a2)+
  115.  
  116.         lea    debug_pc,a1                ;pc.
  117.         move.l    a0,d0
  118.         sub.l    z80_pc_base,d0
  119.         lsr.w    #8,d0
  120.         output_d0_to_a1
  121.         move.l    a0,d0
  122.         sub.l    z80_pc_base,d0
  123.         output_d0_to_a1
  124.  
  125.         lea    debug_next_1,a1                ;x.
  126.         move.b    1(a0),d0
  127.         output_d0_to_a1
  128.  
  129.         lea    debug_next_2,a1                ;xx.
  130.         move.b    2(a0),d0
  131.         output_d0_to_a1
  132.         move.b    1(a0),d0
  133.         output_d0_to_a1
  134.  
  135.         lea    debug_rom_bank,a1            ;rom bank.
  136.         move.b    rom_bank_activated,d0
  137.         output_d0_to_a1
  138.  
  139.         lea    debug_ram_bank,a1            ;ram bank.
  140.         move.l    ram_bank_no,d0
  141.         output_d0_to_a1
  142.  
  143.         lea    debug_de,a1                ;de.
  144.         move.w    gbz80_de,d0
  145.         lsr.w    #8,d0
  146.         output_d0_to_a1
  147.         move.w    gbz80_de,d0
  148.         output_d0_to_a1
  149.  
  150.         lea    debug_bc,a1                ;bc.
  151.         move.w    gbz80_bc,d0
  152.         lsr.w    #8,d0
  153.         output_d0_to_a1
  154.         move.w    gbz80_bc,d0
  155.         output_d0_to_a1
  156.  
  157.         lea    debug_hl,a1                ;hl.
  158.         move.w    gbz80_hl,d0
  159.         lsr.w    #8,d0
  160.         output_d0_to_a1
  161.         move.w    gbz80_hl,d0
  162.         output_d0_to_a1
  163.  
  164.         lea    debug_af,a1                ;af.
  165.         move.w    gbz80_fa,d0
  166.         output_d0_to_a1
  167.         move.w    gbz80_fa,d0
  168.         lsr.w    #8,d0
  169.         output_d0_to_a1
  170.  
  171.         lea    debug_sp,a1                ;sp.
  172.         move.w    d5,d0
  173.         lsr.w    #8,d0
  174.         output_d0_to_a1
  175.         move.w    d5,d0
  176.         output_d0_to_a1
  177.  
  178. debug_output_output:
  179.         move.l    #debug_message_end-debug_message,d3
  180. debug_output_output_size:
  181.         move.l    #debug_message,d2
  182.         move.l    dos_base,a6
  183.         move.l    debug_con_handle,d1
  184.         jsr    Write(a6)
  185.  
  186.         move.b    $bfec01,d6
  187.         not.b    d6
  188.         ror.b    #1,d6
  189.         cmp.b    #$45,d6
  190.         bne.s    debug_output_exit
  191.  
  192.         movem.l    (SP)+,d0-d7/a0-a6
  193.  
  194.         sub.l    a5,a5
  195.         move.b    #1,debug_exit
  196.  
  197.         move.b    (a0)+,d7
  198.         lsl.w    #8,d7                    ;d7 = d7*256.
  199.         jmp    (a1,d7.l)                ;jump and emulate.
  200.  
  201. debug_output_exit:
  202.         movem.l    (SP)+,d0-d7/a0-a6
  203.  
  204.         move.b    (a0)+,d7
  205.         lsl.w    #8,d7                    ;d7 = d7*256.
  206.         jmp    (a1,d7.l)                ;jump and emulate.
  207.  
  208. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  209. ;        memory write debug routines
  210. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  211.  
  212. debug_joypad_wanted:
  213.         movem.l    d0-d7/a0-a6,-(SP)
  214.  
  215.         lea    debug_joy,a1
  216.         move.b    d6,d0
  217.         output_d0_to_a1
  218.  
  219.         move.l    #debug_joy_txt,d2
  220.         move.l    #debug_joy_txt_end-debug_joy_txt,d3
  221.         move.l    dos_base,a6
  222.         move.l    debug_con_handle,d1
  223.         jsr    Write(a6)
  224.  
  225.         movem.l    (SP)+,d0-d7/a0-a6
  226.         rts
  227.  
  228.         ENDIF
  229.  
  230. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  231. ;        fetch the next z80 optcode
  232. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  233.  
  234. fetch_next_i:    MACRO
  235. ;        jmp    jesus
  236.         move.l    a5,d6                    ;test cycles left.
  237.         ble.s    f_xit\@
  238.         IFGT    GAMEBOY_DEBUG
  239.         jmp    debug_output
  240.         ELSE
  241.         move.b    (a0)+,d7
  242.         lsl.w    #8,d7                    ;d7 = d7*256.
  243.         jmp    (a1,d7.l)                ;jump and emulate.
  244.         ENDIF
  245. f_xit\@:    rts
  246.         ENDM
  247.  
  248.  
  249. jesus:        move.l    a5,d6                    ;test cycles left.
  250.         ble.s    f_xita
  251.  
  252.         IFGT    GAMEBOY_DEBUG
  253.         jmp    debug_output
  254.         ELSE
  255.         move.b    (a0)+,d7
  256.         lsl.w    #8,d7                    ;d7 = d7*256.
  257.         jmp    (a1,d7.l)                ;jump and emulate.
  258.         ENDIF
  259.  
  260. f_xita:        rts
  261.  
  262. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  263. ;        z80 emulator, %1011 = znhc
  264. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  265.  
  266. z80_start:    move.l    bank_address,a0                ;the rom area.
  267.         lea    z80_optcode_00,a1            ;xx optcodes.
  268.         move.l    gb_memory,a2                ;pointer to pseudo ram.
  269.         move.l    a0,a3                    ;a3 = base pointer.
  270.         move.l    a0,z80_pc_base
  271.         lea    z80_optc_CB00,a4            ;cbxx optcodes.
  272.         add.l    #$100,a0                ;the beginning.
  273.  
  274.         move.l    #$00D8,d0
  275.         move.l    #$0013,d1
  276.         move.l    #$014D,d2
  277.         move.l    #$0101,d3                ;n = 1!
  278.         move.l    #%00000101,d4
  279.         move.l    #$fffe,d5                ;the stack pointer.
  280.         moveq.l    #0,d7
  281.  
  282.         move.b    #1,h_the_flag                ;h = 1!
  283.  
  284.         move.b    #%0,mbc1_status
  285.         move.l    #1,mbc5_rom_bank            ;b0, b1.
  286.         rts                        ;exit init.
  287.  
  288. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  289. ;        x/5 sweep
  290. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  291.  
  292.         cnop    0,4
  293. z80_cpu_next_sweep:
  294.         moveq.l    #0,d7
  295.         move.l    z80_cycles,a5
  296.  
  297.         IFGT    GAMEBOY_DEBUG
  298.         jmp    debug_output
  299.         ELSE
  300.  
  301.         move.b    (a0)+,d7
  302.         lsl.w    #8,d7                    ;d7 = d7*256.
  303.         jmp    (a1,d7.l)                ;jump and emulate.
  304.         ENDIF
  305.  
  306. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  307. ;        push - command memory supervisor
  308. ;        INPUT:
  309. ;        d6    = h.B, l.B (a 16-bit value to be pushed).
  310. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  311.  
  312.         cnop    0,4
  313. write_d6_stack:    subq.w    #1,d5
  314.         move.l    d6,-(SP)
  315.         lsr.w    #8,d6                    ;d6 = upper data (h.B).
  316.         move.l    d5,d7
  317.  
  318.         move.l    gb_mem_jumps,a6
  319.         jsr    ([a6,d5.l*4])                ;memory write.
  320.  
  321.         subq.w    #1,d5
  322.         move.l    (SP)+,d6
  323.         move.l    d5,d7                    ;d7 = 00BB, because
  324.                                 ;d5 = 00BB.
  325.         move.l    gb_mem_jumps,a6
  326.         jsr    ([a6,d5.l*4])                ;memory write.
  327.  
  328.         fetch_next_i
  329.  
  330.         cnop    0,4
  331. write_d6_stackx:subq.w    #1,d5
  332.         move.l    d6,-(SP)
  333.         move.l    d5,d7
  334.         lsr.w    #8,d6                    ;d6 = upper data (h.B).
  335.  
  336.         move.l    gb_mem_jumps,a6
  337.         jsr    ([a6,d5.l*4])                ;memory write.
  338.  
  339.         subq.w    #1,d5
  340.         move.l    (SP)+,d6
  341.         move.l    d5,d7                    ;d7 = 00BB, because
  342.                                 ;d5 = 00BB.
  343.         move.l    gb_mem_jumps,a6
  344.         jsr    ([a6,d5.l*4])                ;memory write.
  345.         rts
  346.  
  347. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  348. ;        memory related subroutines and checks
  349. ;        INPUT:
  350. ;        d6    = the data (.B).
  351. ;        d7    = address for the write.
  352. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  353.  
  354.         cnop    0,4
  355. echo_down:    lea    (a2,d7.l),a6
  356.         move.b    d6,(a6)
  357.         sub.l    #$2000,a6
  358.         move.b    d6,(a6)
  359.         rts
  360.  
  361.         cnop    0,4
  362. echo_up:    lea    (a2,d7.l),a6
  363.         move.b    d6,(a6)
  364.         add.l    #$2000,a6
  365.         move.b    d6,(a6)
  366.         rts
  367.  
  368.         cnop    0,4
  369. gb_mem_wr:    move.b    d6,(a2,d7.l)
  370.         rts
  371.  
  372.         cnop    0,4
  373. gb_mem_wr_denied:
  374.         rts                        ;no write.
  375.  
  376. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  377. ;        misc memory protection writes
  378. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  379.  
  380.         cnop    0,4
  381. lcd_mode_write:    ;btst    #7,d6
  382.         ;bne.s    lcd_mode_write_done
  383.  
  384.         ;cmp.l    #144,gb_scanlines
  385.         ;blt.s    lcd_mode_write_done
  386.  
  387.         ;or.b    #%10000000,d6
  388.  
  389. lcd_mode_write_done:
  390.         move.b    d6,(a2,d7.l)
  391.         rts
  392.  
  393.         cnop    0,4
  394. lcd_protect:    lea    (a2,d7.l),a6
  395.         and.b    #%01111000,d6
  396.         and.b    #%10000111,(a6)
  397.         or.b    d6,(a6)
  398.  
  399.         move.b    (a6),d6
  400.         and.b    #%11,d6
  401.         beq.s    lcd_write_irq
  402.         cmp.b    #1,d6
  403.         bne.s    lcd_write_no_irq
  404.  
  405. lcd_write_irq:    move.l    a2,a6            ;bug in hardware.
  406.         add.l    #$ff0f,a6
  407.         bset.b    #1,(a6)            ;lcd irq is about to happen.
  408.  
  409. lcd_write_no_irq:
  410.         rts
  411.  
  412.         cnop    0,4
  413. irq_protect_0f:    or.b    #%11100000,d6
  414. ;        cmp.b    (a2,d7.l),d6
  415. ;        beq.s    irq_protect_0f_exit
  416.         move.b    d6,(a2,d7.l)
  417. ;        tst.b    i_flag
  418. ;        beq.s    irq_protect_ff_wowza
  419. irq_protect_0f_exit:
  420.         rts
  421.  
  422.         cnop    0,4
  423. irq_protect_ff:    or.b    #%11100000,d6
  424. ;        cmp.b    (a2,d7.l),d6
  425. ;        beq.s    irq_protect_ff_exit
  426.         move.b    d6,(a2,d7.l)
  427. ;        tst.b    i_flag
  428. ;        beq.s    irq_protect_ff_wowza
  429. irq_protect_ff_exit:
  430.         rts
  431.  
  432.         cnop    0,4
  433. irq_protect_ff_wowza:
  434.         move.l    a5,z80_cycles_left        ;CHECK THIS ONE OUT WITH
  435.         move.b    #1,z80_ei_return        ;KIRBY 2!!!
  436.         move.l    #1,a5
  437. ;        bchg.b    #1,$bfe001
  438.         rts
  439.  
  440.         cnop    0,4
  441. timc_protect:    or.b    #%11111000,d6
  442.         move.b    d6,(a2,d7.l)
  443.         rts
  444.  
  445.         cnop    0,4
  446. clear_divider:    move.b    #0,(a2,d7.l)
  447.         rts
  448.  
  449.         cnop    0,4
  450. sio_register:    move.b    d6,(a2,d7.l)
  451.         rts
  452.  
  453.         cnop    0,4
  454. sio_control:    move.b    d6,(a2,d7.l)
  455.         btst    #7,d6
  456.         bne.s    sio_control_start
  457.         rts
  458.  
  459.         cnop    0,4
  460. sio_control_start:
  461.         btst    #0,d6
  462.         beq.s    sio_control_start_external
  463.  
  464. ;        move.b    #$ff,-1(a2,d7.l)            ;serial off!
  465.         move.b    #8,transfer_counter
  466.         rts
  467.  
  468. sio_control_start_external:
  469.         rts
  470.  
  471. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  472. ;        a rom write has occurred! 8O
  473. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  474.  
  475.         cnop    0,4
  476. no_write:
  477. rom_write:    rts                    ;exit the rom write.
  478.  
  479. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  480. ;        memory related routines
  481. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  482.  
  483.         cnop    0,4
  484. dma_execute:    move.l    a5,-(SP)
  485.         and.l    #$ff,d6                ;d6 = the address (.B).
  486.         cmp.w    #$f1,d6
  487.         ble.s    dma_start_ok
  488.         sub.b    #$f1,d6
  489.  
  490. dma_start_ok:
  491. ;        bchg.b    #1,$bfe001
  492.  
  493.         tst.b    d6
  494.         bge.s    dma_rom
  495. dma_ram:    move.l    a2,a5                ;do a ram read.
  496.         bra.s    dma_move
  497. dma_rom:    move.l    a3,a5                ;do a rom read.
  498.  
  499. dma_move:    lsl.l    #8,d6                ;input fixed.
  500.         add.l    d6,a5                ;a5 = input.
  501.         move.l    a2,a6                ;output is in ram.
  502.         add.l    #$fe00,a6            ;a6 = output (oam).
  503.         moveq.l    #40-1,d7
  504. dma_execute_mv:    move.l    (a5)+,d6
  505.         and.l    #$fffffff0,d6
  506.         and.l    #$0000000f,(a6)
  507.         or.l    d6,(a6)
  508.         addq.l    #4,a6
  509.         dbra    d7,dma_execute_mv        ;execute dma move.
  510.         move.l    (SP)+,a5
  511.         rts
  512.  
  513.         cnop    0,4
  514. do_joystick:
  515.         IFGT    GAMEBOY_DEBUG
  516.         bsr.w    debug_joypad_wanted
  517.         ENDIF
  518.  
  519.         cmp.b    #$03,d6                ;type request?
  520.         beq.s    do_joystick_type_request    ;yes.
  521.  
  522.         btst    #5,d6
  523.         beq.s    do_joystick_but
  524.         btst    #4,d6
  525.         beq.s    do_joystick_dir
  526.  
  527.         or.b    #%00001111,d6            ;both keylines are disabled.
  528.         move.b    d6,(a2,d7.l)
  529.         rts
  530.  
  531.         cnop    0,4
  532. do_joystick_but:btst    #4,d6
  533.         beq.s    do_joystick_both
  534.  
  535.         move.l    d5,-(SP)
  536.         move.b    buttons_byte,d5
  537.         and.b    #%11110000,d6
  538.         and.b    #%00001111,d5
  539.         or.b    d6,d5
  540.         move.b    d5,(a2,d7.l)
  541.         move.l    (SP)+,d5
  542.         rts
  543.  
  544.         cnop    0,4
  545. do_joystick_type_request:
  546.         move.b    #$f0,d6                ;normal gameboy.
  547.  
  548. do_joystick_both:
  549.         movem.l    d5/d4,-(SP)
  550.         move.b    directions_byte,d4
  551.         move.b    buttons_byte,d5
  552.         eor.b    #%11111111,d4
  553.         eor.b    #%11111111,d5
  554.         and.b    #%11110000,d6
  555.         or.b    d4,d5
  556.         or.b    d6,d5
  557.         eor.b    #%00001111,d5
  558.         move.b    d5,(a2,d7.l)
  559.         movem.l    (SP)+,d5/d4
  560.         rts
  561.  
  562.         cnop    0,4
  563. do_joystick_dir:btst    #5,d6
  564.         beq.s    do_joystick_both
  565.  
  566.         move.l    d5,-(SP)
  567.         move.b    directions_byte,d5
  568.         and.b    #%11110000,d6
  569.         and.b    #%00001111,d5
  570.         or.b    d6,d5
  571.         move.b    d5,(a2,d7.l)
  572.         move.l    (SP)+,d5
  573.         rts
  574.  
  575.         cnop    0,4
  576. ly_write:    move.b    #0,(a2,d7.l)
  577.         rts
  578.  
  579.         cnop    0,4
  580. lyc_write:    move.b    d6,(a2,d7.l)
  581.  
  582.         move.l    a2,a6
  583.         add.l    #$ff00,a6
  584.  
  585.         btst.b    #7,$40(a6)            ;lcd enabled?
  586.         beq.s    kcmp_up                ;no.
  587.  
  588.         btst.b    #1,irq_status_flags        ;vbr effect?
  589.         beq.s    kcmp_blank_no_filtering
  590.         move.l    gb_scanlines,d7
  591. ;        beq.s    kcmp_up                ;$00 is off limits.
  592.         cmp.l    #$91,d7
  593.         bge.s    kcmp_up                ;$91-$99 are off limits, too.
  594.  
  595. kcmp_blank_no_filtering:
  596.         move.b    $45(a6),d7            ;d7 = ly compare / lyc.
  597.         cmp.b    $44(a6),d7
  598.         bne.s    klyc_clear            ;not the same.
  599.         bset.b    #2,$41(a6)            ;coincidence occurred.
  600.  
  601.         btst.b    #6,$41(a6)            ;interrupt?
  602.         beq.s    kcmp_up                ;nope. disabled.
  603.  
  604.         btst.b    #1,$ff(a6)            ;lcd controller irq enabled?
  605.         beq.s    kcmp_up                ;no.
  606.  
  607. kcmp_starts:
  608.         IFGT    GAMEBOY_DEBUG
  609.         bsr.w    debug_blank
  610.         ENDIF
  611.  
  612.         bset.b    #1,$0f(a6)            ;lcd occurred.
  613.         bset.b    #2,irq_status_flags        ;lyc occurred.
  614.         bra.s    kcmp_up                ;skip vbr.
  615.  
  616. klyc_clear:    bclr.b    #2,$41(a6)            ;no coincidence.
  617. kcmp_up:    rts
  618.  
  619. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  620. ;        mappers
  621. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  622.  
  623.         cnop    0,4
  624. mbc1_rom_switch:
  625. ;        tst.b    mbc1_status
  626. ;        bne.s    mbc1_in_4_32
  627.  
  628.         and.l    #$ff,d6
  629. mbc1_in_16_8:    cmp.l    rom_banks_mask,d6
  630.         ble.s    mbc1_rom_switch_in_limit
  631.         sub.l    rom_banks_mask,d6
  632.         bra.s    mbc1_in_16_8
  633.  
  634. mbc1_rom_switch_in_limit:
  635.  
  636.         IFGT    GAMEBOY_DEBUG
  637.         move.b    d6,rom_bank_activated
  638.         ENDIF
  639.  
  640.         lsl.l    #8,d6
  641.         lsl.l    #7,d6                    ;d6 = d6 * $8000.
  642.         add.l    rom_32k,d6                ;rom pointer.
  643.         move.l    d6,bank_address
  644.         move.l    d6,a3                    ;update rom pointer.
  645.  
  646.         sub.l    z80_pc_base,a0
  647.         move.w    a0,d7
  648.         blt.s    pc_in_ram_mbc1
  649.         add.l    d6,a0                    ;new rom address base.
  650.         move.l    d6,z80_pc_base
  651.         rts
  652.  
  653.         cnop    0,4
  654. pc_in_ram_mbc1:    add.l    a2,a0                    ;old ram address base.
  655.         rts
  656.  
  657.         cnop    0,4
  658. mbc1_in_4_32:    rts
  659.  
  660.         cnop    0,4
  661. mbc1_rom_mode_select:
  662.         and.b    #%1,d6
  663.         move.b    d6,mbc1_status
  664.         rts
  665.  
  666.         cnop    0,4
  667. mbc1_rom_switch_two_address_lines:
  668.         tst.b    mbc1_status
  669.         bne.s    mbc1_rom_switch_two_address_lines_4_32
  670.  
  671.                                 ;support for 1 & 2
  672.                                 ;MB cartridges!!!
  673.         rts                        ;not here. ;)
  674.  
  675.         cnop    0,4
  676. mbc1_rom_switch_two_address_lines_4_32:
  677.         rts
  678.  
  679.         cnop    0,4
  680. mbc1_ram_protection:
  681.         tst.b    mbc1_status
  682.         beq.s    mbc1_ram_protection_no_changes
  683.  
  684.         and.b    #%00001111,d6
  685.         move.b    d6,mbc1_ram_protection_status
  686.         rts
  687.  
  688.         cnop    0,4
  689. mbc1_ram_protection_no_changes:
  690.         rts
  691.  
  692.         cnop    0,4
  693. mbc1_ram_switch_with_two_rom_address_lines:
  694. ;        tst.b    mbc1_status
  695. ;        bne.s    mbc1_ram_switch_with_two_rom_address_lines_change_ram_bank
  696. ;                                ;support for 1 & 2
  697. ;                                ;MB cartridges!!!
  698. ;        rts                        ;not here. ;)
  699.  
  700. mbc1_ram_switch_with_two_rom_address_lines_change_ram_bank:
  701.         and.l    ram_banks_mask,d6
  702.  
  703.         move.l    ram_bank_no,d7
  704.         cmp.b    d6,d7
  705.         beq.s    mbc1_exit
  706.  
  707.         lsl.l    #8,d7
  708.         lsl.l    #5,d7                    ;8kb banks.
  709.         add.l    memory_banks,d7                ;base address.
  710.         move.l    d6,ram_bank_no                ;new bank number.
  711.  
  712.         move.l    d7,a6                    ;a6 = output.
  713.         move.l    a5,-(SP)
  714.         move.l    a2,a5
  715.         add.l    #$A000,a5                ;a5 = input.
  716.         move.w    #$2000/4/4/2-1,d7
  717. backup_ram:    move.l    (a5)+,(a6)+
  718.         move.l    (a5)+,(a6)+
  719.         move.l    (a5)+,(a6)+
  720.         move.l    (a5)+,(a6)+
  721.         move.l    (a5)+,(a6)+
  722.         move.l    (a5)+,(a6)+
  723.         move.l    (a5)+,(a6)+
  724.         move.l    (a5)+,(a6)+
  725.         dbra    d7,backup_ram
  726.  
  727.         move.l    a2,a6
  728.         add.l    #$A000,a6                ;a6 = output.
  729.         lsl.l    #8,d6
  730.         lsl.l    #5,d6                    ;8kb banks.
  731.         add.l    memory_banks,d6
  732.         move.l    d6,a5                    ;a5 = input.
  733.  
  734.         move.w    #$2000/4/4/2-1,d7
  735. restore_ram:    move.l    (a5)+,(a6)+
  736.         move.l    (a5)+,(a6)+
  737.         move.l    (a5)+,(a6)+
  738.         move.l    (a5)+,(a6)+
  739.         move.l    (a5)+,(a6)+
  740.         move.l    (a5)+,(a6)+
  741.         move.l    (a5)+,(a6)+
  742.         move.l    (a5)+,(a6)+
  743.         dbra    d7,restore_ram
  744.  
  745.         moveq.l    #0,d7
  746.         move.l    (SP)+,a5
  747. mbc1_exit:    rts
  748.  
  749.         cnop    0,4
  750. mbc2_ram_protection:
  751.         and.b    #%1,d6
  752.         move.b    d6,mbc2_ram_protection_status
  753.         rts
  754.  
  755.         cnop    0,4
  756. mbc2_rom_switch:and.l    #$ff,d6
  757.         cmp.l    rom_banks_mask,d6
  758.         ble.s    mbc2_rom_switch_in_limit
  759.         sub.l    rom_banks_mask,d6
  760.         bra.s    mbc2_rom_switch
  761.  
  762. mbc2_rom_switch_in_limit:
  763.  
  764.         IFGT    GAMEBOY_DEBUG
  765.         move.b    d6,rom_bank_activated
  766.         ENDIF
  767.  
  768.         lsl.l    #8,d6
  769.         lsl.l    #7,d6                    ;d6 = d6 * $8000.
  770.         add.l    rom_32k,d6                ;rom pointer.
  771.         move.l    d6,bank_address
  772.         move.l    d6,a3                    ;update rom pointer.
  773.  
  774.         sub.l    z80_pc_base,a0
  775.         move.w    a0,d7
  776.         blt.s    pc_in_ram_mbc2
  777.         add.l    d6,a0                    ;new rom address base.
  778.         move.l    d6,z80_pc_base
  779.         rts
  780.  
  781.         cnop    0,4
  782. pc_in_ram_mbc2:    add.l    a2,a0                    ;old ram address base.
  783.         rts
  784.  
  785. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  786. ;        MBC5
  787. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  788.  
  789.         cnop    0,4
  790. mbc5_ramg:    rts                        ;external ram on/off.
  791.  
  792.         cnop    0,4
  793. mbc5_romb0:    move.b    d6,mbc5_rom_bank0
  794.         move.l    mbc5_rom_bank,d6
  795.  
  796. mbc5_romb0_switch:
  797.         cmp.l    rom_banks_mask,d6
  798.         ble.s    mbc5_romb0_switch_in_limit
  799.         sub.l    rom_banks_mask,d6
  800.         bra.s    mbc5_romb0_switch
  801.  
  802. mbc5_romb0_switch_in_limit:
  803.  
  804.         IFGT    GAMEBOY_DEBUG
  805.         move.b    d6,rom_bank_activated
  806.         ENDIF
  807.  
  808.         lsl.l    #8,d6
  809.         lsl.l    #7,d6                    ;d6 = d6 * $8000.
  810.         add.l    rom_32k,d6                ;rom pointer.
  811.         move.l    d6,bank_address
  812.         move.l    d6,a3
  813.  
  814.         sub.l    z80_pc_base,a0
  815.         move.w    a0,d7
  816.         blt.s    pc_in_ram_mbc5_0
  817.         add.l    d6,a0
  818.         move.l    d6,z80_pc_base
  819.         rts
  820.  
  821.         cnop    0,4
  822. pc_in_ram_mbc5_0:
  823.         add.l    a2,a0
  824.         rts
  825.  
  826.         cnop    0,4
  827. mbc5_romb1:    move.b    d6,mbc5_rom_bank1
  828.         move.l    mbc5_rom_bank,d6
  829.  
  830. mbc5_romb1_switch:
  831.         cmp.l    rom_banks_mask,d6
  832.         ble.s    mbc5_romb1_switch_in_limit
  833.         sub.l    rom_banks_mask,d6
  834.         bra.s    mbc5_romb1_switch
  835.  
  836. mbc5_romb1_switch_in_limit:
  837.  
  838.         IFGT    GAMEBOY_DEBUG
  839.         move.b    d6,rom_bank_activated
  840.         ENDIF
  841.  
  842.         lsl.l    #8,d6
  843.         lsl.l    #7,d6                    ;d6 = d6 * $8000.
  844.         add.l    rom_32k,d6                ;rom pointer.
  845.         move.l    d6,bank_address
  846.         move.l    d6,a3
  847.  
  848.         sub.l    z80_pc_base,a0
  849.         move.w    a0,d7
  850.         blt.s    pc_in_ram_mbc5_1
  851.         add.l    d6,a0
  852.         move.l    d6,z80_pc_base
  853.         rts
  854.  
  855.         cnop    0,4
  856. pc_in_ram_mbc5_1:
  857.         add.l    a2,a0
  858.         rts
  859.  
  860.         cnop    0,4
  861. mbc5_ramb:    and.l    ram_banks_mask,d6
  862.         move.l    ram_bank_no,d7
  863.         cmp.b    d6,d7
  864.         beq.s    mbc5_exit
  865.  
  866.         lsl.l    #8,d7
  867.         lsl.l    #5,d7                    ;8kb banks.
  868.         add.l    memory_banks,d7                ;base address.
  869.         move.l    d6,ram_bank_no                ;new bank number.
  870.  
  871.         move.l    d7,a6                    ;a6 = output.
  872.         move.l    a5,-(SP)
  873.         move.l    a2,a5
  874.         add.l    #$A000,a5                ;a5 = input.
  875.         move.w    #$2000/4/4/2-1,d7
  876. backup_ram_x:    move.l    (a5)+,(a6)+
  877.         move.l    (a5)+,(a6)+
  878.         move.l    (a5)+,(a6)+
  879.         move.l    (a5)+,(a6)+
  880.         move.l    (a5)+,(a6)+
  881.         move.l    (a5)+,(a6)+
  882.         move.l    (a5)+,(a6)+
  883.         move.l    (a5)+,(a6)+
  884.         dbra    d7,backup_ram_x
  885.  
  886.         move.l    a2,a6
  887.         add.l    #$A000,a6                ;a6 = output.
  888.         lsl.l    #8,d6
  889.         lsl.l    #5,d6                    ;8kb banks.
  890.         add.l    memory_banks,d6
  891.         move.l    d6,a5                    ;a5 = input.
  892.  
  893.         move.w    #$2000/4/4/2-1,d7
  894. restore_ram_x:    move.l    (a5)+,(a6)+
  895.         move.l    (a5)+,(a6)+
  896.         move.l    (a5)+,(a6)+
  897.         move.l    (a5)+,(a6)+
  898.         move.l    (a5)+,(a6)+
  899.         move.l    (a5)+,(a6)+
  900.         move.l    (a5)+,(a6)+
  901.         move.l    (a5)+,(a6)+
  902.         dbra    d7,restore_ram_x
  903.  
  904.         moveq.l    #0,d7
  905.         move.l    (SP)+,a5
  906. mbc5_exit:    rts
  907.  
  908. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  909. ;        MBC3
  910. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  911.  
  912.         cnop    0,4
  913. mbc3_rom_switch:and.l    #$ff,d6
  914.         cmp.l    rom_banks_mask,d6
  915.         ble.s    mbc3_rom_switch_in_limit
  916.         sub.l    rom_banks_mask,d6
  917.         bra.s    mbc3_rom_switch
  918.  
  919. mbc3_rom_switch_in_limit:
  920.  
  921.         IFGT    GAMEBOY_DEBUG
  922.         move.b    d6,rom_bank_activated
  923.         ENDIF
  924.  
  925.         lsl.l    #8,d6
  926.         lsl.l    #7,d6                    ;d6 = d6 * $8000.
  927.         add.l    rom_32k,d6                ;rom pointer.
  928.         move.l    d6,bank_address
  929.         move.l    d6,a3                    ;update rom pointer.
  930.  
  931.         sub.l    z80_pc_base,a0
  932.         move.w    a0,d7
  933.         blt.s    pc_in_ram_mbc3
  934.         add.l    d6,a0                    ;new rom address base.
  935.         move.l    d6,z80_pc_base
  936.         rts
  937.  
  938.         cnop    0,4
  939. pc_in_ram_mbc3:    add.l    a2,a0                    ;old ram address base.
  940.         rts
  941.  
  942.         cnop    0,4
  943. mbc3_ram_protection:
  944.         move.b    d6,mbc3_ram_protection_status
  945. mbc3_exit:    rts
  946.  
  947.         cnop    0,4
  948. mbc3_ram_switch_change_ram_bank:
  949.         and.l    ram_banks_mask,d6
  950.         move.l    ram_bank_no,d7
  951.         cmp.b    d7,d6
  952.         beq.s    mbc3_exit
  953.  
  954.         lsl.l    #8,d7
  955.         lsl.l    #5,d7                    ;8kb banks.
  956.         add.l    memory_banks,d7                ;base address.
  957.         move.l    d6,ram_bank_no                ;new bank number.
  958.  
  959.         move.l    d7,a6                    ;a6 = output.
  960.         move.l    a5,-(SP)
  961.         move.l    a2,a5
  962.         add.l    #$A000,a5                ;a5 = input.
  963.         move.w    #$2000/4/4/2-1,d7
  964. backup_ram_n:    move.l    (a5)+,(a6)+
  965.         move.l    (a5)+,(a6)+
  966.         move.l    (a5)+,(a6)+
  967.         move.l    (a5)+,(a6)+
  968.         move.l    (a5)+,(a6)+
  969.         move.l    (a5)+,(a6)+
  970.         move.l    (a5)+,(a6)+
  971.         move.l    (a5)+,(a6)+
  972.         dbra    d7,backup_ram_n
  973.  
  974.         move.l    a2,a6
  975.         add.l    #$A000,a6                ;a6 = output.
  976.         lsl.l    #8,d6
  977.         lsl.l    #5,d6                    ;8kb banks.
  978.         add.l    memory_banks,d6
  979.         move.l    d6,a5                    ;a5 = input.
  980.  
  981.         move.w    #$2000/4/4/2-1,d7
  982. restore_ram_n:    move.l    (a5)+,(a6)+
  983.         move.l    (a5)+,(a6)+
  984.         move.l    (a5)+,(a6)+
  985.         move.l    (a5)+,(a6)+
  986.         move.l    (a5)+,(a6)+
  987.         move.l    (a5)+,(a6)+
  988.         move.l    (a5)+,(a6)+
  989.         move.l    (a5)+,(a6)+
  990.         dbra    d7,restore_ram_n
  991.  
  992.         moveq.l    #0,d7
  993.         move.l    (SP)+,a5
  994.         rts
  995.  
  996.         cnop    0,4
  997. mbc3_no_ram_switch:
  998.         cmp.w    #$8,d6
  999.         blt.s    mbc3_no_ram_switch_exit
  1000.         cmp.w    #$c,d6
  1001.         bgt.s    mbc3_no_ram_switch_exit
  1002.  
  1003.         sub.b    #$8,d6
  1004.         lea    mbc3_latched_sec,a6
  1005.         move.b    (a6,d6.w),d7
  1006.         move.w    #$2000-1,d6
  1007.         move.l    a2,a6
  1008.         add.l    #$a000,a6
  1009.  
  1010. mbc3_output_clock_data:
  1011.         move.b    d7,(a6)+
  1012.         dbra    d6,mbc3_output_clock_data
  1013.  
  1014. mbc3_no_ram_switch_exit:
  1015.         rts
  1016.  
  1017.         cnop    0,4
  1018. mbc3_latch_clock_counter_data:
  1019.         move.b    mbc3_latch_b,mbc3_latch_a
  1020.         move.b    d6,mbc3_latch_b
  1021.  
  1022.         tst.b    mbc3_latch_a
  1023.         bne.s    mbc3_latch_clock_counter_data_exit
  1024.         cmp.b    #1,d6
  1025.         bne.s    mbc3_latch_clock_counter_data_exit
  1026.  
  1027. mbc3_latch_clock_counter_data_execute_latch:
  1028.         move.b    mbc3_sec,mbc3_latched_sec
  1029.         move.b    mbc3_min,mbc3_latched_min
  1030.         move.b    mbc3_hrs,mbc3_latched_hrs
  1031.         move.b    mbc3_dayl,mbc3_latched_dayl
  1032.         move.b    mbc3_dayh,mbc3_latched_dayh
  1033.  
  1034. mbc3_latch_clock_counter_data_exit:
  1035.         rts
  1036.  
  1037. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  1038. ;        RETI back
  1039. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  1040.  
  1041.         cnop    0,4
  1042. reti_back:    move.l    a2,a6
  1043.         add.l    #$ff0f,a6                ;(interrupt flags).
  1044.         move.b    (a6),d7
  1045.         and.b    #%11111,d7
  1046.         beq.s    no_more_irqs
  1047.  
  1048.         move.l    a0,d6                    ;stack the pc.
  1049.         sub.l    z80_pc_base,d6
  1050.         move.b    #1,i_flag                ;disable interrupts.
  1051.  
  1052.         btst    #0,d7
  1053.         bne.s    irq_i
  1054.         btst    #1,d7
  1055.         bne.s    irq_ii
  1056.         btst    #2,d7
  1057.         bne.s    irq_iii
  1058.         btst    #3,d7
  1059.         bne.w    irq_iv
  1060.  
  1061. irq_v:        bclr.b    #4,(a6)
  1062.  
  1063.         IFEQ    Z80_MODE
  1064.         bsr.w    write_d6_stackx
  1065.         ELSE
  1066.         subq.w    #2,d5
  1067.         ror.w    #8,d6
  1068.         move.w    d6,(a2,d5.l)
  1069.         ENDIF
  1070.  
  1071.         lea    $60(a3),a0
  1072.         move.l    a3,z80_pc_base                ;rom base.
  1073.  
  1074. no_more_irqs:
  1075.         fetch_next_i
  1076.  
  1077.         cnop    0,4
  1078. irq_i:        bclr.b    #0,(a6)
  1079.  
  1080.         IFEQ    Z80_MODE
  1081.         bsr.w    write_d6_stackx
  1082.         ELSE
  1083.         subq.w    #2,d5
  1084.         ror.w    #8,d6
  1085.         move.w    d6,(a2,d5.l)
  1086.         ENDIF
  1087.  
  1088.         lea    $40(a3),a0
  1089.         move.l    a3,z80_pc_base                ;rom base.
  1090.  
  1091.         fetch_next_i
  1092.  
  1093.         cnop    0,4
  1094. irq_ii:        bclr.b    #1,(a6)
  1095.  
  1096.         IFEQ    Z80_MODE
  1097.         bsr.w    write_d6_stackx
  1098.         ELSE
  1099.         subq.w    #2,d5
  1100.         ror.w    #8,d6
  1101.         move.w    d6,(a2,d5.l)
  1102.         ENDIF
  1103.  
  1104.         lea    $48(a3),a0
  1105.         move.l    a3,z80_pc_base                ;rom base.
  1106.  
  1107.         fetch_next_i
  1108.  
  1109.         cnop    0,4
  1110. irq_iii:    bclr.b    #2,(a6)
  1111.  
  1112.         IFEQ    Z80_MODE
  1113.         bsr.w    write_d6_stackx
  1114.         ELSE
  1115.         subq.w    #2,d5
  1116.         ror.w    #8,d6
  1117.         move.w    d6,(a2,d5.l)
  1118.         ENDIF
  1119.  
  1120.         lea    $50(a3),a0
  1121.         move.l    a3,z80_pc_base                ;rom base.
  1122.  
  1123.         fetch_next_i
  1124.  
  1125.         cnop    0,4
  1126. irq_iv:        bclr.b    #3,(a6)
  1127.  
  1128.         IFEQ    Z80_MODE
  1129.         bsr.w    write_d6_stackx
  1130.         ELSE
  1131.         subq.w    #2,d5
  1132.         ror.w    #8,d6
  1133.         move.w    d6,(a2,d5.l)
  1134.         ENDIF
  1135.  
  1136.         lea    $58(a3),a0
  1137.         move.l    a3,z80_pc_base                ;rom base.
  1138.  
  1139.         fetch_next_i
  1140.  
  1141. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  1142. ;        misc memory reads
  1143. ;««««««««««««««««««««««««««««««««««««««««««««««»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  1144.  
  1145. READ_D2_TO_D6:    MACRO
  1146.         tst.w    d2
  1147.         blt.s    read_to_\@
  1148.         move.b    (a3,d2.l),d6
  1149.         bra.s    read_to_exit_\@
  1150.         cnop    0,4
  1151. read_to_\@:    move.b    (a2,d2.l),d6
  1152. read_to_exit_\@:    
  1153.         ENDM
  1154.  
  1155. READW_D5_TO_D7:    MACRO
  1156.         tst.w    d5
  1157.         blt.s    readw_to_\@
  1158.         move.w    (a3,d5.l),d7
  1159.         bra.s    readw_to_exit_\@
  1160.         cnop    0,4
  1161. readw_to_\@:    move.w    (a2,d5.l),d7
  1162. readw_to_exit_\@:    
  1163.         ENDM
  1164.